package com.michael.leetcode;

import org.junit.Test;

import java.util.Arrays;

public class IsRobotBounded_1025 {

    /*1041. 困于环中的机器人
    在无限的平面上，机器人最初位于 (0, 0) 处，面朝北方。注意:

    北方向 是y轴的正方向。
    南方向 是y轴的负方向。
    东方向 是x轴的正方向。
    西方向 是x轴的负方向。
    机器人可以接受下列三条指令之一：

    "G"：直走 1 个单位
    "L"：左转 90 度
    "R"：右转 90 度
    机器人按顺序执行指令 instructions，并一直重复它们。

    只有在平面中存在环使得机器人永远无法离开时，返回 true。否则，返回 false。

    示例 1：

    输入：instructions = "GGLLGG"
    输出：true
    解释：机器人最初在(0,0)处，面向北方。
            “G”:移动一步。位置:(0,1)方向:北。
            “G”:移动一步。位置:(0,2).方向:北。
            “L”:逆时针旋转90度。位置:(0,2).方向:西。
            “L”:逆时针旋转90度。位置:(0,2)方向:南。
            “G”:移动一步。位置:(0,1)方向:南。
            “G”:移动一步。位置:(0,0)方向:南。
    重复指令，机器人进入循环:(0,0)——>(0,1)——>(0,2)——>(0,1)——>(0,0)。
    在此基础上，我们返回true。
    示例 2：

    输入：instructions = "GG"
    输出：false
    解释：机器人最初在(0,0)处，面向北方。
            “G”:移动一步。位置:(0,1)方向:北。
            “G”:移动一步。位置:(0,2).方向:北。
    重复这些指示，继续朝北前进，不会进入循环。
    在此基础上，返回false。
    示例 3：

    输入：instructions = "GL"
    输出：true
    解释：机器人最初在(0,0)处，面向北方。
            “G”:移动一步。位置:(0,1)方向:北。
            “L”:逆时针旋转90度。位置:(0,1).方向:西。
            “G”:移动一步。位置:(- 1,1)方向:西。
            “L”:逆时针旋转90度。位置:(- 1,1)方向:南。
            “G”:移动一步。位置:(- 1,0)方向:南。
            “L”:逆时针旋转90度。位置:(- 1,0)方向:东方。
            “G”:移动一步。位置:(0,0)方向:东方。
            “L”:逆时针旋转90度。位置:(0,0)方向:北。
    重复指令，机器人进入循环:(0,0)——>(0,1)——>(- 1,1)——>(- 1,0)——>(0,0)。
    在此基础上，我们返回true。

    提示：
     1 <= instructions.length <= 100
    instructions[i] 仅包含 'G', 'L', 'R'*/
    public boolean isRobotBounded(String instructions) {
        int[] start = {0, 0};
        int[] current = {0, 0};
        // 上一次的朝向 0 y正方向 1 X正方向 2  y负方向 3 x 负方向
        int lastForward = 0;
        char[] charArray = instructions.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            if (charArray[i] == 'L') {
                lastForward = switch (lastForward) {
                    case 0 -> 3;
                    case 1 -> 0;
                    case 2 -> 1;
                    default -> 2;
                };
            } else if (charArray[i] == 'R') {
                lastForward = switch (lastForward) {
                    case 0 -> 1;
                    case 1 -> 2;
                    case 2 -> 3;
                    default -> 0;
                };
            } else {
                switch (lastForward) {
                    case 0 -> current[1] = current[1] + 1;
                    case 1 -> current[0] = current[0] + 1;
                    case 2 -> current[1] = current[1] - 1;
                    default -> current[0] = current[0] - 1;
                }
            }
        }

        /*思路
        当机器人执行完指令 instructions 后，它的位置和方向均有可能发生变化。
        如果它的位置仍位于原点，那么不管它此时方向是什么，机器人都将永远无法离开。
        如果它的位置不在原点，那么需要考虑此时机器人的方向：
        如果机器人仍然朝北，那么机器人可以不会陷入循环。假设执行完一串指令后，机器人的位置是 (x,y) 且不为原点，方向仍然朝北，那么执行完第二串指令后，机器人的位置便成为 (2×x,2×y)，会不停地往外部移动，不会陷入循环。
        如果机器人朝南，那么执行第二串指令时，机器人的位移会与第一次相反，即第二次的位移是 (−x,−y)，并且结束后会回到原来的方向。这样一来，每两串指令之后，机器人都会回到原点，并且方向朝北，机器人会陷入循环。
        如果机器人朝东，即右转了 90°。这样一来，每执行一串指令，机器人都会右转 90°。那么第一次和第三次指令的方向是相反的，第二次和第四次指令的方向是相反的，位移之和也为 0，这样一来，每四次指令之后，机器人都会回到原点，
        并且方向朝北，机器人会陷入循环。如果机器人朝西，也是一样的结果。
        因此，机器人想要摆脱循环，在一串指令之后的状态，必须是不位于原点且方向朝北。*/
        if (Arrays.equals(start, current)){
            return true;
        }else {
            return lastForward != 0;
        }
    }



    public boolean isRobotBounded1(String instructions) {
        int[] start = {0, 0};
        int[] current = {0, 0};
        // 上一次的朝向 0 y正方向 1 X正方向 2  y负方向 3 x 负方向
        int lastForward = 0;
        char[] charArray = instructions.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            if (charArray[i] == 'L') {
                lastForward = switch (lastForward) {
                    case 0 -> 3;
                    case 1 -> 0;
                    case 2 -> 1;
                    default -> 2;
                };
            } else if (charArray[i] == 'R') {
                lastForward = switch (lastForward) {
                    case 0 -> 1;
                    case 1 -> 2;
                    case 2 -> 3;
                    default -> 0;
                };
            } else {
                switch (lastForward) {
                    case 0 -> current[1] = current[1] + 1;
                    case 1 -> current[0] = current[0] + 1;
                    case 2 -> current[1] = current[1] - 1;
                    default -> current[0] = current[0] - 1;
                }
            }

        }


        return false;
    }

    @Test
    public void test() {
        String instructions = "GL";
        isRobotBounded(instructions);

    }
}
